﻿using H.Hands;
using H.KML.KeyBoards;
using H.KML.Mouses;
using H.Types;
using System;

namespace H.KML
{
    /// <summary>
    /// 幽灵键鼠模块
    /// </summary>
    public class KMHand : IHand
    {
        /// <summary>
        /// 内部存储幽灵键鼠实例
        /// </summary>
        internal readonly MCUAPP.IKML _KM;


        public KMHand() : base()
        {
            _KM = new MCUAPP.KML();
            _KM.OpenDevice();
        }

        /// <inheritdoc/>
        public bool AllKeyUp()
        {
            return _KM.KeyUpAll() == 1;
        }

        /// <inheritdoc/>
        public bool AllMouseUp()
        {
            return _KM.MouseUpAll() == 1;
        }



        public IMouse LeftMouse()
        {
            return new KMLMouse(this);
        }

        public IMouse MiddleMouse()
        {
            return new KMMMouse(this);
        }

        public IMouse RightMouse()
        {
            return new KMRMouse(this);
        }

        /// <summary>
        /// 将键码枚举翻译成对应的按键值
        /// </summary>
        /// <param name="key">驱动无关键码</param>
        /// <returns></returns>
        protected string TranslateKey(HandKey key)
        {
            switch (key)
            {
                case HandKey.ESC:
                    return "Esc";

                case HandKey.D0:
                    return "0";
                case HandKey.D1:
                    return "1";
                case HandKey.D2:
                    return "2";
                case HandKey.D3:
                    return "3";
                case HandKey.D4:
                    return "4";
                case HandKey.D5:
                    return "5";
                case HandKey.D6:
                    return "6";
                case HandKey.D7:
                    return "7";
                case HandKey.D8:
                    return "8";
                case HandKey.D9:
                    return "9";

                case HandKey.Ctrl:
                case HandKey.Alt:
                case HandKey.Shift:
                case HandKey.Tab:
                case HandKey.Backspace:
                case HandKey.CapsLock:
                case HandKey.NumLock:
                case HandKey.Insert:
                case HandKey.Win:
                case HandKey.Enter:
                case HandKey.Space:
                case HandKey.F1:
                case HandKey.F2:
                case HandKey.F3:
                case HandKey.F4:
                case HandKey.F5:
                case HandKey.F6:
                case HandKey.F7:
                case HandKey.F8:
                case HandKey.F9:
                case HandKey.F10:
                case HandKey.F11:
                case HandKey.F12:

                case HandKey.A:
                case HandKey.B:
                case HandKey.C:
                case HandKey.D:
                case HandKey.E:
                case HandKey.F:
                case HandKey.G:
                case HandKey.H:
                case HandKey.I:
                case HandKey.J:
                case HandKey.K:
                case HandKey.L:
                case HandKey.M:
                case HandKey.N:
                case HandKey.O:
                case HandKey.P:
                case HandKey.Q:
                case HandKey.R:
                case HandKey.S:
                case HandKey.T:
                case HandKey.U:
                case HandKey.V:
                case HandKey.W:
                case HandKey.X:
                case HandKey.Y:
                case HandKey.Z:

                case HandKey.Num0:
                case HandKey.Num1:
                case HandKey.Num2:
                case HandKey.Num3:
                case HandKey.Num4:
                case HandKey.Num5:
                case HandKey.Num6:
                case HandKey.Num7:
                case HandKey.Num8:
                case HandKey.Num9:
                case HandKey.NumDiv:
                case HandKey.NumMul:
                case HandKey.NumAdd:
                case HandKey.NumDec:
                case HandKey.NumEnter:
                case HandKey.NumDot:

                case HandKey.Left:
                case HandKey.Right:
                case HandKey.Up:
                case HandKey.Down:
                case HandKey.PageUp:
                case HandKey.PageDown:
                case HandKey.Home:
                case HandKey.End:
                    return key.ToString();

                case HandKey.Comma:
                    return ",";
                case HandKey.Dot:
                    return ".";
                case HandKey.Question:
                    return "?";
                default:
                    throw new NotImplementedException();
            }
        }

        ///<inheritdoc/>
        public IKeyBoard CreateKeys(params HandKey[] keys)
        {
            string[] keyStr = new string[keys.Length];
            for(int i = 0; i < keys.Length; i++)
            {
                keyStr[i] = TranslateKey(keys[i]);
            }
            return new KMKeys(this, keyStr);
        }

        /// <inheritdoc/>
        public IKeyBoard CreateKey(HandKey key)
        {
            return new KMKey(this, TranslateKey(key));
        }

        /// <inheritdoc/>
        public bool GetCapsLock(out bool lightOn)
        {
            switch (_KM.GetCapsLock())
            {
                case 1:
                    lightOn = false;
                    return true;
                case 2:
                    lightOn = true;
                    return true;
                case 3:
                default:
                    lightOn = false;
                    return false;
            }
        }

        /// <inheritdoc/>
        public bool GetNumLock(out bool lightOn)
        {
            switch (_KM.GetNumLock())
            {
                case 1:
                    lightOn = false;
                    return true;
                case 2:
                    lightOn = true;
                    return true;
                case 3:
                default:
                    lightOn = false;
                    return false;
            }
        }

        /// <inheritdoc/>
        public bool InputString(string sentence)
        {
            return _KM.SayString(sentence) > 0;
        }


        /// <inheritdoc/>
        public bool MousePoint(ref Pos point)
        {
            if (_KM.GetCursorPos(out int x, out int y) == 1)
            {
                point.X = x;
                point.Y = y;
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <inheritdoc/>
        public bool MoveTo(Pos point)
        {
            return _KM.SimulationMove(point.X, point.Y) > 0;
        }

        /// <inheritdoc/>
        public bool MoveToRelative(Pos offset)
        {
            return _KM.MoveToR(offset.X, offset.Y) > 0;
        }

        /// <inheritdoc/>
        public bool WheelDown(int count)
        {
            while (count > 127)
            {
                if (_KM.WheelDown(127) == 0)
                {
                    return false;
                }
                count -= 127;
            }
            return _KM.WheelDown(count) == 1;
        }

        /// <inheritdoc/>
        public bool WheelUp(int count)
        {
            while (count > 127)
            {
                if (_KM.WheelUp(127) == 0)
                {
                    return false;
                }
                count -= 127;
            }
            return _KM.WheelUp(count) == 1;
        }

        /// <inheritdoc/>
        public bool Scroll(int count)
        {
            if (count > 0)
            {
                return WheelDown(count);
            }
            else
            {
                return WheelUp(-count);
            }
        }

        /// <inheritdoc/>
        protected virtual void Dispose(bool disposing)
        {

        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        ~KMHand()
        {
            Dispose(false);
        }
    }
}
